home *** CD-ROM | disk | FTP | other *** search
- unit ObjectArrayUnit;
-
- interface
-
- type
- TTinyName = string[3];
- TTinyObject = class(TObject)
- private
- FValue: integer;
- FName: TTinyName;
- public
- property Value: integer read FValue write FValue;
- property Name: TTinyName read FName write FName;
- end;
-
- TFastTinyObject = class(TTinyObject)
- public
- class procedure InitObjectStore(Count: Cardinal);
- class procedure FreeObjectStore;
- class function NewInstance: TObject; override;
- procedure FreeInstance; override;
- end;
-
- TFasterTinyObject = class(TFastTinyObject)
- public
- class function NewInstance: TObject; override;
- procedure FreeInstance; override;
- end;
-
- implementation
-
- uses SysUtils, Classes;
-
- type
- TObjectStore = class(TObject)
- private
- FMemoryPool: PChar;
- FPoolSize: Cardinal;
- FAllocatedCount: Cardinal;
- FCurrentFree: PChar;
- public
- constructor Create(PoolSize: Cardinal);
- destructor Destroy; override;
- function AllocateInstance(InstanceSize: Cardinal): TObject;
- procedure DeallocateInstance(InstanceSize: Cardinal);
- end;
-
- { TObjectStore }
-
- constructor TObjectStore.Create(PoolSize: Cardinal);
- begin
- inherited Create;
- FPoolSize := PoolSize;
- GetMem(FMemoryPool, FPoolSize);
- FCurrentFree := FMemoryPool;
- end;
-
- destructor TObjectStore.Destroy;
- begin
- if FAllocatedCount <> 0 then
- raise Exception.Create('References into the ObjectStore has not been released!');
- FreeMem(FMemoryPool, FPoolSize);
- inherited Destroy;
- end;
-
- function TObjectStore.AllocateInstance(InstanceSize: Cardinal): TObject;
- begin
- if Self = nil then
- raise Exception.Create('Objectstore has not been allocated yet.');
- Result := TObject(FCurrentFree);
- Inc(FCurrentFree, InstanceSize);
- if Longint(FMemoryPool) + FPoolSize < Longint(FCurrentFree) then
- raise Exception.Create('Not enough space allocated in objectstore to allocate instance');
- Inc(FAllocatedCount);
- end;
-
- procedure TObjectStore.DeallocateInstance(InstanceSize: Cardinal);
- begin
- if Self = nil then
- raise Exception.Create('Objectstore has not been allocated yet.');
- if FAllocatedCount = 0 then
- raise Exception.Create('Deallcated more instances from the objectstore than was allocated');
- Dec(FAllocatedCount);
- end;
-
- { TFastTinyObject }
-
- const
- FTinyObjectStore: TObjectStore = nil;
-
- class procedure TFastTinyObject.InitObjectStore(Count: Cardinal);
- begin
- FTinyObjectStore := TObjectStore.Create(Count * Self.InstanceSize);
- end;
-
- class procedure TFastTinyObject.FreeObjectStore;
- begin
- FTinyObjectStore.Free;
- FTinyObjectStore := nil;
- end;
-
- class function TFastTinyObject.NewInstance: TObject;
- begin
- Result := FTinyObjectStore.AllocateInstance(Self.InstanceSize);
- Result := InitInstance(Result);
- end;
-
- procedure TFastTinyObject.FreeInstance;
- begin
- FTinyObjectStore.DeallocateInstance(Self.InstanceSize);
- end;
-
- { TFasterTinyObject }
-
- class function TFasterTinyObject.NewInstance: TObject;
- type
- PClass = ^TClass;
- begin
- Result := TObject(FTinyObjectStore.FCurrentFree);
- Inc(FTinyObjectStore.FCurrentFree, SizeOf(TFastTinyObject));
- PClass(Result)^ := Self; // Init VMT, don't init fields.
- end;
-
- procedure TFasterTinyObject.FreeInstance;
- begin
- // Do nothing!
- end;
-
- end.
-